/*
 * drv_tim.c
 *
 *  Created on: Dec 17, 2022
 *      Author: hongwei_zhu
 */
#include "hal_tim.h"

void (*pwm_update_ck)(void) = NULL;

void TIM1_UP_IRQHandler(void) __attribute__((interrupt()));
void TIM2_IRQHandler(void) __attribute__((interrupt()));
void TIM3_IRQHandler(void) __attribute__((interrupt()));
void TIM4_IRQHandler(void) __attribute__((interrupt()));




void TIM1_UP_IRQHandler(void)
{
    if( TIM_GetITStatus( TIM1, TIM_IT_Update ) != RESET )
    {
        TIM_ClearITPendingBit( TIM1, TIM_IT_Update );
        if(pwm_update_ck) pwm_update_ck();
    }
}

void drv_tim2_init(u16 hz)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure = {0};
    NVIC_InitTypeDef        NVIC_InitStructure = {0};

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    TIM_TimeBaseInitStructure.TIM_Period = 2000000 / hz;
    TIM_TimeBaseInitStructure.TIM_Prescaler = SystemCoreClock / 2000000;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0x00;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);

    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    TIM_Cmd(TIM2, DISABLE);
}
void drv_tim2_start(void)
{
    TIM_Cmd(TIM2, ENABLE);
}
void drv_tim2_pause(void)
{
    TIM_Cmd(TIM2, DISABLE);
}
void TIM2_IRQHandler(void)
{
    if( TIM_GetITStatus( TIM2, TIM_IT_Update ) != RESET )
    {
        TIM_ClearITPendingBit( TIM2, TIM_IT_Update );
        timer2.callback();
    }
}
struct gtim_type timer2 = {drv_tim2_init,drv_tim2_start,drv_tim2_pause,0};


void drv_tim3_init(u16 hz)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure = {0};
    NVIC_InitTypeDef        NVIC_InitStructure = {0};

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    TIM_TimeBaseInitStructure.TIM_Period = 100000 / hz;
    TIM_TimeBaseInitStructure.TIM_Prescaler = SystemCoreClock / 100000;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0x00;
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);

    TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);

    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    TIM_Cmd(TIM3, DISABLE);
}
void drv_tim3_start(void)
{
    TIM_Cmd(TIM3, ENABLE);
}
void drv_tim3_pause(void)
{
    TIM_Cmd(TIM3, DISABLE);
}
void TIM3_IRQHandler(void)
{
    if( TIM_GetITStatus( TIM3, TIM_IT_Update ) != RESET )
    {
        TIM_ClearITPendingBit( TIM3, TIM_IT_Update );
        timer3.callback();
    }
}
struct gtim_type timer3 = {drv_tim3_init,drv_tim3_start,drv_tim3_pause,0};

void drv_tim4_init(u16 hz)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure = {0};
    NVIC_InitTypeDef        NVIC_InitStructure = {0};

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

    TIM_TimeBaseInitStructure.TIM_Period = 2000000 / hz;
    TIM_TimeBaseInitStructure.TIM_Prescaler = SystemCoreClock / 2000000;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0x00;
    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStructure);

    TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);

    NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    TIM_Cmd(TIM4, DISABLE);
}
void drv_tim4_start(void)
{
    TIM_Cmd(TIM4, ENABLE);
}
void drv_tim4_pause(void)
{
    TIM_Cmd(TIM4, DISABLE);
}
void TIM4_IRQHandler(void)
{
    if( TIM_GetITStatus( TIM4, TIM_IT_Update ) != RESET )
    {
        TIM_ClearITPendingBit( TIM4, TIM_IT_Update );
        timer4.callback();
    }
}
struct gtim_type timer4 = {drv_tim4_init,drv_tim4_start,drv_tim4_pause,0};


//
//void task1_loop(void)
//{
//    printf("this is a test\r\n");
//}
//void main(void)
//{
//        timer2.callback = task1_loop;
//        timer2.init(2);
//        timer2.start();
//        while(1)
//        {
//        }
//}

